#ifndef __AP_AVI_ENCODER_H__
#define __AP_AVI_ENCODER_H__

#include "AviPackerV3.h"

//=====================================================================================================
/* avi encode configure set */
#define AVI_ENCODE_PCM_BUFFER_NO	22			//audio record pcm use buffer number

//audio format
#define AVI_ENCODE_AUDIO_FORMAT WAVE_FORMAT_PCM //0: no audio, WAVE_FORMAT_PCM, WAVE_FORMAT_IMA_ADPCM and WAVE_FORMAT_ADPCM
#define AVI_AUDIO_RECORD_TIMER	ADC_AS_TIMER_F	//adc use timer, C ~ F

//avi file max size
#define AVI_ENCODE_CAL_DISK_SIZE_EN 0			//0: disable, 1: enable

//video format
#define C_XVID_FORMAT			0x44495658
#define C_MJPG_FORMAT			0x47504A4D
#define AVI_ENCODE_VIDEO_FORMAT C_MJPG_FORMAT	//only support mjpeg

//=====================================================================================================
//=====================================================================================================
/* avi encode status */
#define C_AVI_ENCODE_IDLE		0x00000000
#define C_AVI_ENCODE_PACKER0	0x00000001
#define C_AVI_ENCODE_AUDIO		0x00000002

//#define C_AVI_ENCODE_VIDEO		0x00000004
//#define C_AVI_ENCODE_SCALER		0x00000008
#define C_AVI_ENCODE_SENSOR 0x00000010

//#define C_AVI_ENCODE_PACKER1		0x00000020
//#define C_AVI_ENCODE_MD			0x00000040
#define C_AVI_ENCODE_USB_WEBCAM 0x00000080

#define C_AVI_ENCODE_START		0x00000100

/****************************************************************************/
typedef struct AviEncVidPara_s
{
	// Sensor
	INT16U	sensor_width;
	INT16U	sensor_height;
	INT16U	clip_width;
	INT16U	clip_height;

	// Display
	INT16U	zoom_width;
	INT16U	zoom_height;
	INT16U	zoom_w_start;
	INT16U	zoom_h_start;
	
	INT16U	zoom_width_r;
	INT16U	zoom_height_r;
	INT16U	zoom_w_start_r;
	INT16U	zoom_h_start_r;
	
	INT16U	display_width;
	INT16U	display_height;
	INT16U	display_offset;


	INT16U	pip_x;
	INT16U	pip_y;
	INT16U	pip_width;
	INT16U	pip_height;

	INT32U	video_format;		// video encode format
	INT8U	dwScale;			// dwScale
	INT8U	dwRate;				// dwRate
	INT16U	quality_value;		// video encode quality
	INT16U	enter_ap_mode;
	INT16U	encode_width;		// video encode width
	INT16U	encode_height;		// videoe ncode height
	INT16U	sensor_width_r;		// sensor width
	INT16U	sensor_height_r;	// sensor height
	INT16U	encode_width_r;		// video encode width
	INT16U	encode_height_r;	// videoe ncode height
	INT16U	dwRate_r;
} AviEncVidPara_t;

//+++ AVI_ENCODER_STATE.C
extern AviEncVidPara_t	AviEncVidPara, *pAviEncVidPara;
extern OS_EVENT			*videoEncodeApQ;
extern OS_EVENT			*videoEncodeMsgAck;

/****************************************************************************/
extern void				avi_encode_init(void);

/****************************************************************************/
typedef struct AviEncAudPara_s
{
	//audio encode
	INT32U	audio_format;						// audio encode format
	INT16U	audio_sample_rate;					// sample rate
	INT16U	channel_no;							// channel no, 1:mono, 2:stereo
	INT8U	*work_mem;							// wave encode work memory
	INT32U	pack_size;							// wave encode package size in byte
	INT32U	pack_buffer_addr;
	INT32U	pcm_input_size;						// wave encode pcm input size in short
	INT32U	pcm_input_addr[AVI_ENCODE_PCM_BUFFER_NO];
} AviEncAudPara_t;

typedef struct AviEncPacker_s
{
	void					*avi_workmem;

	INT16S					file_handle;
	INT16S					file_handle_tmp;
	INT16S					txt_handle;

	//avi video info
	GP_AVI_AVISTREAMHEADER	*p_avi_vid_stream_header;
	INT32U					bitmap_info_cblen;	// bitmap header length
	GP_AVI_BITMAPINFO		*p_avi_bitmap_info;

	//avi audio info
	GP_AVI_AVISTREAMHEADER	*p_avi_aud_stream_header;
	INT32U					wave_info_cblen;	// wave header length
	GP_AVI_PCMWAVEFORMAT	*p_avi_wave_info;

	//avi packer
	INT32U					task_prio;
	void					*index_write_buffer;
	INT32U					index_buffer_size;	// AviPacker index buffer size in byte

	char					*gps_buf;
	INT32U					gps_buf_size;
	INT32U					gps_buf_used;

	OS_EVENT				*return_queue;		// the queue used to return jpeg buffer
	INT32U					return_msg;			// the msg used to return jpeg buffer
	INT8U					print_flag;
	INT8U					front_or_rear;
} AviEncPacker_t;

typedef struct AviEncPara_s
{
	INT8U	source_type;						// SOURCE_TYPE_FS or SOURCE_TYPE_USER_DEFINE

	//avi file info
	INT32U	avi_encode_status;					// 0:IDLE

	//allow record size
	INT64U	disk_free_size;						// disk free size
	INT32U	record_total_size;					// AviPacker storage to disk total size
} AviEncPara_t;

extern AviEncPara_t		*pAviEncPara;
extern AviEncAudPara_t	*pAviEncAudPara;
extern AviEncPacker_t	*pAviEncPacker0;
extern AviEncPacker_t	*pAviEncPacker1;

//USB Webcam
extern OS_EVENT *USBCamApQ;
extern OS_EVENT *USBAudioApQ;

#define USB_AUDIO_PCM_SAMPLES	(2000)
#define AVI_AUDIO_PCM_SAMPLES	(AUD_REC_SAMPLING_RATE/4)

typedef struct
{
	INT32U	FrameSize;
	INT32U	AddrFrame;
	INT8U	IsoSendState;
} ISOTaskMsg;

//jpeg header
extern INT8U	jpeg_422_q90_header[];

//avi encode state
extern INT32U	avi_enc_packer_start(AviEncPacker_t *pAviEncPacker);
extern INT32U	avi_enc_packer_init(AviEncPacker_t *pAviEncPacker);
extern INT32U	avi_enc_packer_stop(AviEncPacker_t *pAviEncPacker, INT8U continue_flag);

//extern INT32U	avi_enc_packer_switch_file(AviEncPacker_t *pAviEncPacker, INT16S fd_new, INT16S fd_txt_new);
extern INT32S	vid_enc_preview_start(void);
extern INT32S	vid_enc_preview_stop(void);
extern INT32S	avi_enc_start(void);
extern INT32S	avi_enc_stop(void);
extern INT32S	avi_enc_save_jpeg(void);
extern INT32S	avi_packer_err_handle(INT32S ErrCode);
extern void (*pfn_avi_encode_put_data) (void *WorkMem, AVIPACKER_FRAME_INFO *pFrameInfo);

//audio task
extern INT32S	avi_adc_gps_register(void);
extern void		avi_adc_gsensor_data_register(OS_EVENT **msgq_id, INT32U *msg_id);
extern INT32S	avi_adc_record_task_create(INT8U pori);
extern INT32S	avi_audio_record_start(void);
extern INT32S	avi_audio_record_restart(void);
extern INT32S	avi_audio_record_stop(void);
extern void		avi_audio_record_entry(void *parm);

extern INT32S	avi_encode_set_file_handle_and_caculate_free_size(AviEncPacker_t *pAviEncPacker, INT16S FileHandle, INT16S txt_FileHandle);
extern INT16S	avi_encode_close_file(AviEncPacker_t *pAviEncPacker);
extern INT32S	avi_encode_set_avi_header(AviEncPacker_t *pAviEncPacker);

//status
extern void		avi_encode_set_status(INT32U bit);
extern void		avi_encode_clear_status(INT32U bit);
extern INT32S	avi_encode_get_status(void);
extern INT32S	avi_encode_packer_memory_alloc(void);

extern INT32S	avi_encode_disk_size_is_enough(INT32S cb_write_size);

extern INT32S	avi_audio_memory_allocate(INT32U cblen);
extern void		avi_audio_memory_free(void);
extern INT32U	avi_audio_get_next_buffer(void);

extern INT32S	avi_adc_double_buffer_put(INT16U *data, INT32U cwlen, OS_EVENT *os_q);
extern INT32U	avi_adc_double_buffer_set(INT16U *data, INT32U cwlen);
extern INT32S	avi_adc_dma_status_get(void);
extern void		avi_adc_double_buffer_free(void);
extern void		avi_adc_hw_start(INT16U sampling_rate);
extern void		avi_adc_hw_stop(void);

extern INT8U	ap_state_config_date_stamp_get(void);

/****************************************************************************/
extern INT32S	vid_enc_preview_buf_to_dummy(void);
extern INT32S	vid_enc_preview_buf_to_display(INT32U mode);
#endif // __AP_AVI_ENCODER_H__
